package com.popo.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class SelectSockets {
	public static int PORT_NUMBER = 12024;
	private ByteBuffer buffer   = ByteBuffer.allocate(1024);
	public static void main(String[] args) {

	}

	public void go(int port) throws IOException {
		System.out.println("Listening on port " + port);

		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		ServerSocket serverSocket = serverSocketChannel.socket();
		Selector selector = Selector.open();
		serverSocket.bind(new InetSocketAddress(port));
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		while (true) {
			int n = selector.select();
			if (n == 0) {
				continue;
			}
			java.util.Iterator<SelectionKey> it = selector.selectedKeys()
					.iterator();
			while (it.hasNext()) {
				SelectionKey key = it.next();
				if (key.isAcceptable()) {
					ServerSocketChannel server = (ServerSocketChannel) key
							.channel();
					SocketChannel channel = server.accept();
					registerChannel(selector, channel, SelectionKey.OP_READ);
					sayHello(channel);
				}else if (key.isReadable()) {
					readDataFromSocket(key);
				}
				it.remove();
			}
		}
	}

	private void readDataFromSocket(SelectionKey key) throws IOException {
		// TODO Auto-generated method stub	
		SocketChannel socketChannel = (SocketChannel) key.channel();
		int count;
		buffer.clear();
		while((count=socketChannel.read(buffer))>0){
			buffer.flip();
			while(buffer.hasRemaining()){
				socketChannel.write(buffer);
			}
			buffer.clear();
		}
		
		if(count<0){
			socketChannel.close();
		}
	}

	private void sayHello(SocketChannel channel) throws IOException {
		// TODO Auto-generated method stub
		buffer.clear();
		buffer.put("hi there!\r\n".getBytes());
		buffer.flip();
		channel.write(buffer);
	}

	private void registerChannel(Selector selector, SocketChannel channel,
			int opRead) throws IOException {
		// TODO Auto-generated method stub
		if (channel == null)
			return;
		channel.configureBlocking(false);

		channel.register(selector, opRead);
	}
}
